﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;

namespace ServerApp.Tool
{
    public class TimeEventHandler
    {
        private static TimeEventHandler handler;
        public static TimeEventHandler Instance {
            get { if (handler == null) { handler = new TimeEventHandler(); } return handler; }
        }

        List<TimeEventModel> missions;


        /// <summary>
        /// 计时器
        /// </summary>
        private Timer timer;
        System.Threading.Mutex wait;

        private TimeEventHandler() {
            wait = new System.Threading.Mutex();
            missions = new List<TimeEventModel>();
            timer = new Timer(14);
            timer.Elapsed += TimeCallback;
            timer.Start();
        }

        void TimeCallback(object sender, ElapsedEventArgs e)
        {
            lock (missions)
            {
                wait.WaitOne();
                for (int i = 0; i < missions.Count; i++) {
                    if (DateTime.Now.Ticks >= missions[i].tigtime) {
                        if (missions[i].de != null) { 
                            missions[i].de();
                            missions[i].tigtime += missions[i].wtime;
                        }
                        if (missions[i].count > 0) { missions[i].count--; }
                    }
                }

                for (int j = 0; j < missions.Count; j++) {
                    if (missions[j].count == 0) {
                        RemoveMission(missions[j]);
                    }
                }

                wait.ReleaseMutex();
            }
        }


        public void AddMission(TimeEventModel model) {
            lock (missions) {
                wait.WaitOne();
                if (!missions.Contains(model)) {
                    missions.Add(model);
                }
                wait.ReleaseMutex();
            }
        }

        public void RemoveMission(TimeEventModel model) {
            lock (missions) {
                wait.WaitOne();
                if (missions.Contains(model)) {
                    missions.Remove(model);
                }
                wait.ReleaseMutex();
            }
        }

    }

    public class TimeEventModel {
        public int count;
        public TimeEventDe de;
        public long tigtime;
        public long wtime;
        /// <summary>
        /// 定时任务模型
        /// </summary>
        /// <param name="d">委托</param>
        /// <param name="t">时间间隔 秒为单位</param>
        /// <param name="c">执行次数 -1表示无限执行，直到外部移除</param>
        public TimeEventModel(TimeEventDe d, float t, int c = 1) {
            de = d;
            wtime =(long)(t*1000*1000*10);
            tigtime = DateTime.Now.Ticks+wtime;
            count = c;
        }
    }

    /// <summary>
    /// 事件委托
    /// </summary>
    public delegate void TimeEventDe();
}
